package com.mall.mymall.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mall.mymall.common.Result;
import com.mall.mymall.dao.dto.*;
import com.mall.mymall.dao.entity.OrderDetails;
import com.mall.mymall.dao.entity.Orders;
import com.mall.mymall.dao.entity.Products;
import com.mall.mymall.service.OrderDetailsService;
import com.mall.mymall.service.OrdersService;
import com.mall.mymall.dao.dto.querypage.OrderPageRequest;
import com.mall.mymall.service.RefundsService;
import com.mall.mymall.service.UsersService;
import com.mall.mymall.utils.JwtTokenProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author 十里坡
 * @since 2025-03-06
 */
@RestController
@RequestMapping("/orders")
public class OrdersController {
    @Autowired
    private OrdersService ordersService;

    @Autowired
    private OrderDetailsService orderDetailsService;

    @Autowired
    private RefundsService refundsService;

    @Autowired
    UsersService usersService;

    @Autowired
    JwtTokenProvider jwtTokenProvider;

    /**
     * 处理订单分页查询请求
     *
     * @param orderPageRequest 订单分页查询请求对象，包含查询条件和分页参数
     * @return 返回查询结果，包括订单数据和分页信息
     * <p>
     * 此方法通过POST请求处理订单的分页查询逻辑它首先创建一个空的QueryDto对象，
     * 然后调用ordersService的pageOrders方法填充这个对象如果查询结果为空，
     * 则返回失败的Result对象；否则，返回包含查询结果的QueryDto对象
     */
    @PostMapping("/pageQuery")
    public Result<QueryDto<OrderDto>> pageOrders(@RequestBody OrderPageRequest orderPageRequest) {
        // 初始化查询结果对象
        QueryDto<OrderDto> orderDtoQueryDto = new QueryDto<>();
        // 执行分页查询逻辑
        orderDtoQueryDto = ordersService.pageOrders(orderPageRequest);
        // 检查查询结果是否为空，如果为空则返回查询失败的响应
        if (orderDtoQueryDto == null) {
            return Result.fail("查询失败");
        }
        // 返回查询成功的响应，包含查询结果
        return Result.success(orderDtoQueryDto);
    }

    @GetMapping("/orderList")
    public Result<QueryDto<Orders>> orderList(@RequestParam Integer page, @RequestParam Integer size, HttpServletRequest request) {
        String username = jwtTokenProvider.getUsernameFromToken(jwtTokenProvider.getJwtFromRequest(request));
        if (username == null) {
            return Result.fail("请先登录");
        }
        Integer userId = usersService.getUserByUsername(username).getUserId();
        List<Orders> orders = ordersService.orderList(page, size, userId);
        QueryDto<Orders> ordersQueryDto = new QueryDto<>();
        ordersQueryDto.setRecords(orders);
        QueryWrapper<Orders> ordersQueryWrapper = new QueryWrapper<>();
        ordersQueryWrapper.eq("user_id", userId);
        int count = ordersService.count(ordersQueryWrapper);
        ordersQueryDto.setTotal(count);
        return Result.success(ordersQueryDto);
    }

    /**
     * 删除订单及其详细信息
     *
     * @param orderId 订单ID
     * @return 删除结果
     */
    @DeleteMapping("/delete/{orderId}")
    public Result<String> delete(@PathVariable Integer orderId) {

        try {
            ordersService.deleteById(orderId);
            orderDetailsService.remove(new QueryWrapper<OrderDetails>().eq("order_id", orderId));
            return Result.success("删除成功");
        } catch (Exception e) {
            return Result.fail("删除失败");
        }
    }

    /**
     * 更新订单信息
     * <p>
     * 本接口用于更新特定订单的详细信息它期望在请求体中接收更新后的订单数据，
     * 并通过URL路径参数指定需要更新的订单ID如果更新成功，返回成功信息；
     * 如果更新失败，返回失败信息
     *
     * @param orderDto 订单更新数据，包含需要更新的订单信息
     * @param orderId  需要更新的订单ID
     * @return 更新结果信息，包括是否成功
     */
    @PutMapping("/update/{orderId}")
    public Result<String> update(@RequestBody OrderDto orderDto, @PathVariable Integer orderId) {

        try {
            ordersService.update(orderDto, orderId);
            return Result.success("修改成功");
        } catch (Exception e) {
            return Result.fail("修改失败");
        }
    }

    /**
     * 添加订单接口
     *
     * @param orderDto 订单信息，包含订单的各种详细数据
     * @return Result<OrderDto> 返回订单添加结果，包括是否成功和相关数据
     */
    @PostMapping("/add")
    public Result<OrderDto> addOrder(@RequestBody OrderDto orderDto) {
        try {
            // 调用服务层方法添加订单
            ordersService.creatOrder(orderDto);
            // 根据添加结果返回成功或失败信息
            return Result.success(orderDto);
        } catch (Exception e) {
//            return Result.fail(e.getMessage());
            return Result.fail("添加失败" + e.getMessage());
        }
    }

    @PostMapping("/addOrder")
    public Result<String> addOrder(@RequestBody List<OrderProductDto> productsList, HttpServletRequest request) {
        String username = jwtTokenProvider.getUsernameFromToken(jwtTokenProvider.getJwtFromRequest(request));
        if (username == null) {
            return Result.fail("请先登录");
        }
        Integer userId = usersService.getUserByUsername(username).getUserId();
        for (OrderProductDto products : productsList) {
            products.setOrderPrice(BigDecimal.valueOf(Integer.parseInt(products.getPrice())* products.getQuantity()));
        }
        try {
            // 调用服务层方法添加订单
            ordersService.addOrder(productsList,userId);
            // 根据添加结果返回成功或失败信息
            return Result.success("添加成功");
        } catch (Exception e) {
            return Result.fail("添加失败" + e.getMessage());
        }
    }


    /**
     * 更新订单状态
     *
     * @param orderStatus 新的订单状态
     * @param orderId     订单ID
     * @return Result<String> 更新结果
     */
    @PutMapping("/changeStatus/{orderId}/{orderStatus} ")
    public Result<String> changeStatus(@PathVariable String orderStatus, @PathVariable Integer orderId) {
        // 调用服务层方法更改订单状态
        // 根据更新结果返回相应的信息
        try {
            ordersService.changeStatus(orderStatus, orderId);
            return Result.fail("修改失败");
        } catch (Exception e) {
            return Result.success("修改成功");
        }
    }

    /**
     * 处理退款申请的接口
     * 通过订单ID和请求体中的信息来申请退款
     *
     * @param orderId 订单ID，用于标识需要申请退款的订单
     * @param body    包含退款申请相关信息的请求体，如退款原因等
     * @return 返回处理结果，包括是否成功启动退款流程
     */
    @PutMapping("/applyRefund/{orderId}")
    public Result<String> applyRefund(@PathVariable Integer orderId, @RequestBody Map<String, String> body) {
        return ordersService.applyRefund(orderId, body);
    }

    /**
     * 订单数据统计
     *
     * @param orderDto 请求参数列表
     * @return 返回结果集
     */
    @PostMapping("/count")
    public Result<OrderCountVo> ordersCount(@RequestBody OrderDto orderDto) {
        try {
            return Result.success(ordersService.orderCount(orderDto));
        } catch (Exception e) {
            return Result.fail("获取数据失败");
        }
    }

    @GetMapping("/getStatus/{orderId}")
    public Result<String> getStatus(@PathVariable Integer orderId) {
        try {
            return Result.success(ordersService.getStatus(orderId));
        } catch (Exception e) {
            return Result.fail("获取数据失败");
        }
    }
}

